home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 1 / Mac Magazin and MacEasy Magazine CD - Issue 01.iso / Sharewarebibliothek / Powermac / C64 / SOURCE / Instructions.c < prev    next >
Text File  |  1994-06-06  |  13KB  |  378 lines

  1. /*
  2.     Commodore 64 Emulator v0.4      Earle F. Philhower III 
  3.     Copyright (C) 1993-4            (st916w9r@dunx1.ocs.drexel.edu)
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #include "Processor.h"
  21. #include "Instructions.h"
  22. #include "Stack.h"
  23. #include "Modes.h"
  24. #include "Error.h"
  25.  
  26. /*    Rather than using multiplication and division to do the BCD math, it's implemented
  27.  *    with lookup tables--faster and easier to code in 68K assembly.
  28.  */
  29. unsigned char    bcd2dec[256]    =
  30.     {
  31. /* 0x00    */    0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  32. /* 0x10 */    10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,
  33. /* 0x20 */    20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,
  34. /* 0x30 */    30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,
  35. /* 0x40 */    40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,
  36. /* 0x50 */    50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,
  37. /* 0x60 */    60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,
  38. /* 0x70 */    70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,
  39. /* 0x80 */    80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
  40. /* 0x90 */    90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,
  41. /* 0xA0 */    100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
  42. /* 0xB0 */    110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
  43. /* 0xC0 */    120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,
  44. /* 0xD0 */    130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
  45. /* 0xE0 */    140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,
  46. /* 0xF0 */    150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165
  47.     };
  48.  
  49. unsigned char    dec2bcd[100]    =
  50.     {
  51.             0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
  52.             0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
  53.             0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,
  54.             0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,
  55.             0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
  56.             0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
  57.             0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
  58.             0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
  59.             0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
  60.             0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99
  61.     };
  62.  
  63. void i00() {
  64.     PushWord(pc);
  65.     flags |= BKC;
  66.     Push(flags);
  67.     flags &= ~BKC;
  68.     pc=WordAt(IrqTo); }
  69. void i01() { ORA(IndirectXAddr); pc++; }
  70. void i05() { ORA(ZeroPageAddr); pc++; }
  71. void i06() { ASL(ZeroPageAddr); pc++; }
  72. void i08() { Push(flags); }
  73. void i09() { a |= ImmediateByte(); FlagsNZ(a); pc++; }
  74. void i0a() {
  75.     if (a&128) flags |= CAR;
  76.     else flags &= ~CAR;
  77.     a=a<<1;
  78.     FlagsNZ(a); }
  79. void i0d() { ORA(AbsoluteAddr); pc+=2; }
  80. void i0e() { ASL(AbsoluteAddr); pc+=2; }
  81. void i10() { BCL(NEG); }
  82. void i11() { ORA(IndirectYAddr); pc++; }
  83. void i15() { ORA(ZeroPageXAddr); pc++; }
  84. void i16() { ASL(ZeroPageXAddr); pc++; }
  85. void i18() { CLR(CAR); }
  86. void i19() { ORA(AbsoluteYAddr); pc+=2; }
  87. void i1d() { ORA(AbsoluteXAddr); pc+=2; }
  88. void i1e() { ASL(AbsoluteXAddr); pc+=2; }
  89. void i20() { PushWord(pc+1); pc=WordAt(pc); }
  90. void i21() { AND(IndirectXAddr); pc++; }
  91. void i24() { BIT(ZeroPageAddr); pc++; }
  92. void i25() { AND(ZeroPageAddr); pc++; }
  93. void i26() { ROL(ZeroPageAddr); pc++; }
  94. void i28() { flags = Pop(); }
  95. void i29() { a &= ImmediateByte(); FlagsNZ(a); pc++; }
  96. void i2a() {
  97.     if (flags&CAR) {
  98.         if ((a&128)==0) flags &=~CAR;
  99.         a=(a<<1)|1; }
  100.     else {
  101.         if(a&128)flags|=CAR;
  102.         a=a<<1; }
  103.     FlagsNZ(a);
  104. }
  105. void i2c() { BIT(AbsoluteAddr); pc+=2; }
  106. void i2d() { AND(AbsoluteAddr); pc+=2; }
  107. void i2e() { ROL(AbsoluteAddr); pc+=2; }
  108. void i30() { BST(NEG); }
  109. void i31() { AND(IndirectYAddr); pc++; }
  110. void i35() { AND(ZeroPageXAddr); pc++; }
  111. void i36() { ROL(ZeroPageXAddr); pc++; }
  112. void i38() { SET(CAR); }
  113. void i39() { AND(AbsoluteYAddr); pc+=2; }
  114. void i3d() { AND(AbsoluteXAddr); pc+=2; }
  115. void i3e() { ROL(AbsoluteXAddr); pc+=2; }
  116. void i40() { flags=Pop(); PopWord(pc); }
  117. void i41() { EOR(IndirectXAddr); pc++; }
  118. void i45() { EOR(ZeroPageAddr); pc++; }
  119. void i46() { LSR(ZeroPageAddr); pc++; }
  120. void i48() { Push(a); }
  121. void i49() { a ^= ImmediateByte(); FlagsNZ(a); pc++; }
  122. void i4a() { 
  123.     flags &=~(CAR+NEG+ZER);
  124.     if (a&1) flags |=CAR;
  125.     if (a=a>>1); else flags |=ZER;
  126. }
  127. void i4c() { pc=WordAt(pc); }
  128. void i4d() { EOR(AbsoluteAddr); pc+=2; }
  129. void i4e() { LSR(AbsoluteAddr); pc+=2; }
  130. void i50() { BCL(OVF); }
  131. void i51() { EOR(IndirectYAddr); pc++; }
  132. void i55() { EOR(ZeroPageXAddr); pc++; }
  133. void i56() { LSR(ZeroPageXAddr); pc++; }
  134. void i58() { CLR(INT); }
  135. void i59() { EOR(AbsoluteYAddr); pc+=2; }
  136. void i5d() { EOR(AbsoluteXAddr); pc+=2; }
  137. void i5e() { LSR(AbsoluteXAddr); pc+=2; }
  138. void i60() { PopWord(pc); pc++; }
  139. void i61() { ADC(IndirectXAddr); pc++; }
  140. void i65() { ADC(ZeroPageAddr); pc++; }
  141. void i66() { ROR(ZeroPageAddr); pc++; }
  142. void i68() { a=Pop(); FlagsNZ(a); }
  143. void i69() {
  144.     register word data;
  145.     data=ImmediateByte();
  146.     if (flags&DEC) {
  147.         data = bcd2dec[data]+bcd2dec[a]+((flags&CAR)?1:0);
  148.         flags &= ~(CAR+OVF+NEG+ZER);
  149.         if (data>99) {
  150.             flags|=CAR+OVF;
  151.             data -=100; }
  152.         if (data==0) flags |= ZER;
  153.         else flags |= data&128;
  154.         a=dec2bcd[data];}
  155.     else {
  156.         data += a+((flags&CAR)?1:0);
  157.         flags &= ~(CAR+OVF+NEG+ZER);
  158.         if (data>255) {
  159.             flags|=OVF+CAR;
  160.             data &=255; }
  161.         if (data==0) flags |= ZER;
  162.         else flags |= data&128;
  163.         a=data; }
  164.     pc++;
  165. }
  166. void i6a() {
  167.     if (flags&CAR) {
  168.         if ((a&1)==0) flags &=~CAR;
  169.         a=(a>>1)|128; }
  170.     else {
  171.         if(a&1) flags|=CAR;
  172.         a=a>>1; }
  173.     FlagsNZ(a);
  174. }
  175. void i6c() { register word ta; ta=WordAt(pc); pc=WordAt(ta); }
  176. void i6d() { ADC(AbsoluteAddr); pc+=2; }
  177. void i6e() { ROR(AbsoluteAddr); pc+=2; }
  178. void i70() { BST(OVF); }
  179. void i71() { ADC(IndirectYAddr); pc++; }
  180. void i75() { ADC(ZeroPageXAddr); pc++; }
  181. void i76() { ROR(ZeroPageXAddr); pc++; }
  182. void i78() { SET(INT); }
  183. void i79() { ADC(AbsoluteYAddr); pc+=2; }
  184. void i7d() { ADC(AbsoluteXAddr); pc+=2; }
  185. void i7e() { ROR(AbsoluteXAddr); pc+=2; }
  186. void i81() { STA(IndirectXAddr); pc++; }
  187. void i84() { STY(ZeroPageAddr); pc++; }
  188. void i85() { STA(ZeroPageAddr); pc++; }
  189. void i86() { STX(ZeroPageAddr); pc++; }
  190. void i88() { y--; FlagsNZ(y); }
  191. void i8a() { a=x; FlagsNZ(a); }
  192. void i8c() { STY(AbsoluteAddr); pc+=2; }
  193. void i8d() { STA(AbsoluteAddr); pc+=2; }
  194. void i8e() { STX(AbsoluteAddr); pc+=2; }
  195. void i90() { BCL(CAR); }
  196. void i91() { STA(IndirectYAddr); pc++; }
  197. void i94() { STY(ZeroPageXAddr); pc++; }
  198. void i95() { STA(ZeroPageXAddr); pc++; }
  199. void i96() { STX(ZeroPageYAddr); pc++; }
  200. void i98() { a=y; FlagsNZ(a); }
  201. void i99() { STA(AbsoluteYAddr); pc+=2; }
  202. void i9a() { sp=x; }
  203. void i9d() { STA(AbsoluteXAddr); pc+=2; }
  204. void ia0() { y=ImmediateByte(); FlagsNZ(y); pc++; }
  205. void ia1() { LDA(IndirectXAddr); pc++; }
  206. void ia2() { x=ImmediateByte(); FlagsNZ(x); pc++; }
  207. void ia4() { LDY(ZeroPageAddr); pc++; }
  208. void ia5() { LDA(ZeroPageAddr); pc++; }
  209. void ia6() { LDX(ZeroPageAddr); pc++; }
  210. void ia8() { y=a; FlagsNZ(y); }
  211. void ia9() { a=ImmediateByte(); FlagsNZ(a); pc++; }
  212. void iaa() { x=a; FlagsNZ(x); }
  213. void iac() { LDY(AbsoluteAddr); pc+=2; }
  214. void iad() { LDA(AbsoluteAddr); pc+=2; }
  215. void iae() { LDX(AbsoluteAddr); pc+=2; }
  216. void ib0() { BST(CAR); }
  217. void ib1() { LDA(IndirectYAddr); pc++; }
  218. void ib4() { LDY(ZeroPageXAddr); pc++; }
  219. void ib5() { LDA(ZeroPageXAddr); pc++; }
  220. void ib6() { LDX(ZeroPageYAddr); pc++; }
  221. void ib8() { CLR(OVF); }
  222. void ib9() { LDA(AbsoluteYAddr); pc+=2; }
  223. void iba() { x=sp; }
  224. void ibc() { LDY(AbsoluteXAddr); pc+=2; }
  225. void ibd() { LDA(AbsoluteXAddr); pc+=2; }
  226. void ibe() { LDX(AbsoluteYAddr); pc+=2; }
  227. void ic0() {
  228.     register byte tbyte;
  229.     tbyte=ImmediateByte();
  230.     flags &=~(CAR+ZER+NEG);
  231.     if (y==tbyte) flags |=CAR+ZER;
  232.     else if (y>tbyte) flags |=CAR;
  233.     else flags |=NEG;
  234.     pc++;
  235. }
  236. void ic1() { CMP(IndirectXAddr); pc++; }
  237. void ic4() { CPY(ZeroPageAddr); pc++; }
  238. void ic5() { CMP(ZeroPageAddr); pc++; }
  239. void ic6() { DECR(ZeroPageAddr); pc++; }
  240. void ic8() { y++; FlagsNZ(y); }
  241. void ic9() {
  242.     register byte tbyte;
  243.     tbyte=ImmediateByte();
  244.     flags &=~(CAR+ZER+NEG);
  245.     if (a==tbyte) flags |=CAR+ZER;
  246.     else if (a>tbyte) flags |=CAR;
  247.         else flags |=NEG;
  248.     pc++;
  249. }
  250. void ica() { x--; FlagsNZ(x); }
  251. void icc() { CPY(AbsoluteAddr); pc+=2; }
  252. void icd() { CMP(AbsoluteAddr); pc+=2; }
  253. void ice() { DECR(AbsoluteAddr); pc+=2; }
  254. void id0() { BCL(ZER); }
  255. void id1() { CMP(IndirectYAddr); pc++; }
  256. void id5() { CMP(ZeroPageXAddr); pc++; }
  257. void id6() { DECR(ZeroPageXAddr); pc++; }
  258. void id8() { CLR(DEC); }
  259. void id9() { CMP(AbsoluteYAddr); pc+=2; }
  260. void idd() { CMP(AbsoluteXAddr); pc+=2; }
  261. void ide() { DECR(AbsoluteXAddr); pc+=2; }
  262. void ie0() {
  263.     register byte tbyte;
  264.     tbyte=ImmediateByte();
  265.     flags &=~(CAR+ZER+NEG);
  266.     if (x==tbyte) flags |=CAR+ZER;
  267.     else if (x>tbyte) flags |=CAR;
  268.     else flags |=NEG;
  269.     pc++;
  270. }
  271. void ie1() { SBC(IndirectXAddr); pc++; }
  272. void ie4() { CPX(ZeroPageAddr); pc++; }
  273. void ie5() { SBC(ZeroPageAddr); pc++; }
  274. void ie6() { INCR(ZeroPageAddr); pc++; }
  275. void ie8() { x++; FlagsNZ(x); }
  276. void ie9() {
  277.     register int data;
  278.     data=ImmediateByte();
  279.     if (flags&DEC) {
  280.         data = bcd2dec[a]-bcd2dec[data]-((flags&CAR)?0:1);
  281.         flags &= ~(CAR+ZER+NEG+OVF);
  282.         if (data==0) flags |=ZER+CAR;
  283.         else if (data>0) flags |=CAR;
  284.             else {
  285.                 flags|=NEG;
  286.                 data +=100; }
  287.         a=dec2bcd[data]; }
  288.     else {
  289.         data = a-data-((flags&CAR)?0:1);
  290.         flags &=~(CAR+ZER+OVF+NEG);
  291.         if (data==0) flags |= ZER+CAR;
  292.         else if (data>0) flags |= CAR;
  293.             else flags|=OVF;
  294.         data &= 255;
  295.         flags |= data&128;
  296.         a=data; }
  297.     pc++; 
  298. }
  299. void iea() {}
  300. void iec() { CPX(AbsoluteAddr); pc+=2; }
  301. void ied() { SBC(AbsoluteAddr); pc+=2; }
  302. void iee() { INCR(AbsoluteAddr); pc+=2; }
  303. void if0() { BST(ZER); }
  304. void if1() { SBC(IndirectYAddr); pc++; }
  305. void if5() { SBC(ZeroPageXAddr); pc++; }
  306. void if6() { INCR(ZeroPageXAddr); pc++; }
  307. void if8() { SET(DEC); }
  308. void if9() { SBC(AbsoluteYAddr); pc+=2; }
  309. void ifd() { SBC(AbsoluteXAddr); pc+=2; }
  310. void ife() { INCR(AbsoluteXAddr); pc+=2; }
  311. void iff() { TrapExecute(); }
  312.  
  313. void ini()
  314. {
  315. #ifdef MACSBUG
  316.     DebugStr("\pNonImplemented!");
  317. #endif
  318.     pc++;
  319. }
  320.  
  321. int InstructionInitialize()
  322. {
  323.     return kNoError;
  324. }
  325.  
  326. void (* instruct[256]) () = {
  327.     i00, i01, ini, ini, ini, i05, i06, ini,
  328.     i08, i09, i0a, ini, ini, i0d, i0e, ini,
  329.     i10, i11, ini, ini, ini, i15, i16, ini,
  330.     i18, i19, ini, ini, ini, i1d, i1e, ini,
  331.     i20, i21, ini, ini, i24, i25, i26, ini,
  332.     i28, i29, i2a, ini, i2c, i2d, i2e, ini,
  333.     i30, i31, ini, ini, ini, i35, i36, ini,
  334.     i38, i39, ini, ini, ini, i3d, i3e, ini,
  335.     i40, i41, ini, ini, ini, i45, i46, ini,
  336.     i48, i49, i4a, ini, i4c, i4d, i4e, ini,
  337.     i50, i51, ini, ini, ini, i55, i56, ini,
  338.     i58, i59, ini, ini, ini, i5d, i5e, ini,
  339.     i60, i61, ini, ini, ini, i65, i66, ini,
  340.     i68, i69, i6a, ini, i6c, i6d, i6e, ini,
  341.     i70, i71, ini, ini, ini, i75, i76, ini,
  342.     i78, i79, ini, ini, ini, i7d, i7e, ini,
  343.     ini, i81, ini, ini, i84, i85, i86, ini,
  344.     i88, ini, i8a, ini, i8c, i8d, i8e, ini,
  345.     i90, i91, ini, ini, i94, i95, i96, ini,
  346.     i98, i99, i9a, ini, ini, i9d, ini, ini,
  347.     ia0, ia1, ia2, ini, ia4, ia5, ia6, ini,
  348.     ia8, ia9, iaa, ini, iac, iad, iae, ini,
  349.     ib0, ib1, ini, ini, ib4, ib5, ib6, ini,
  350.     ib8, ib9, iba, ini, ibc, ibd, ibe, ini,
  351.     ic0, ic1, ini, ini, ic4, ic5, ic6, ini,
  352.     ic8, ic9, ica, ini, icc, icd, ice, ini,
  353.     id0, id1, ini, ini, ini, id5, id6, ini,
  354.     id8, id9, ini, ini, ini, idd, ide, ini,
  355.     ie0, ie1, ini, ini, ie4, ie5, ie6, ini,
  356.     ie8, ie9, iea, ini, iec, ied, iee, ini,
  357.     if0, if1, ini, ini, ini, if5, if6, ini,
  358.     if8, if9, ini, ini, ini, ifd, ife, iff};
  359.  
  360. byte cycletime[256]={
  361. /*00*/    7, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0,
  362. /*10*/    3, 5, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
  363. /*20*/    6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0,
  364. /*30*/    3, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
  365. /*40*/    6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0,
  366. /*50*/    3, 6, 0, 0, 0, 3, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
  367. /*60*/    6, 6, 0, 0, 0, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0,
  368. /*70*/    3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
  369. /*80*/    0, 6, 0, 0, 6, 3, 3, 0, 2, 0, 2, 0, 4, 4, 4, 0,
  370. /*90*/    2, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 0, 5, 0, 0,
  371. /*A0*/    2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0,
  372. /*B0*/    3, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 5, 5, 5, 0,
  373. /*C0*/    2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
  374. /*D0*/    3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 0,
  375. /*E0*/    2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
  376. /*F0*/    3, 6, 0, 0, 0, 4, 6, 0, 2, 5, 0, 0, 0, 5, 7, 1 };
  377.  
  378.